package com.iking.housekeeping.controller.role;

import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.iking.housekeeping.common.CodeEnum;
import com.iking.housekeeping.common.ReturnCode;
import com.iking.housekeeping.entity.menu.SysMenu;
import com.iking.housekeeping.entity.role.Role;
import com.iking.housekeeping.entity.rolemenu.RoleMenu;
import com.iking.housekeeping.httpbean.role.reqbean.InsertRole;
import com.iking.housekeeping.httpbean.role.reqbean.ReturnRole;
import com.iking.housekeeping.httpbean.role.reqbean.UpdateRole;
import com.iking.housekeeping.service.menu.MenuService;
import com.iking.housekeeping.service.role.RoleService;
import com.iking.housekeeping.service.romenu.RoleMenuService;
import com.iking.housekeeping.util.CodeUtil;
import com.iking.housekeeping.util.UUIDUtil;
import com.iking.housekeeping.util.token.WebTokenUtil;

/**
 * 角色管理Controller
 * 
 * @author 张重阳 秦甫杰
 *
 */
@RestController
@RequestMapping("/role")
public class RoleController {

	@Autowired
	private RoleService roleService;

	@Autowired
	private RoleMenuService roleMenuService;

	@Autowired
	private MenuService menuService;

	/**
	 * 角色的添加
	 * 
	 * @param role
	 * @param bindingResult
	 * @return
	 */
	@Transactional
	@PostMapping("/insertRole")
	public ReturnCode insertRole(@RequestBody @Valid InsertRole insertRole, BindingResult bindingResult) {
		// 判断参数是否合法
		if (bindingResult.hasErrors()) {
			String msg = bindingResult.getFieldError().getDefaultMessage();
			return new ReturnCode(CodeEnum.FAIL, msg, null);
		}
		// 判断角色名称是否存在
		if (roleService.selectRoleByName(insertRole.getRoleName()) != null) {
			return new ReturnCode(CodeEnum.FAIL_IS_HAVE);
		}
		Role role = new Role(insertRole.getRoleName(), UUIDUtil.getUUID(), insertRole.getRolePCode());
		// 查询子菜单
		List<Role> roleList = roleService.selectRoleByPCode(role.getRolePCode(), null);
		// 通过父级菜单和查询到子级菜单的长度获取正确的编号信息
		role.setRoleCode(CodeUtil.getCodeByPCode(role.getRolePCode(), roleList.size()));
		// 添加角色
		roleService.addRole(role);

		// 添加角色菜单关联
		List<RoleMenu> lists = new ArrayList<RoleMenu>();
		for (String menus : insertRole.getListMenu()) {
			RoleMenu rMenu = new RoleMenu(UUIDUtil.getUUID(), role.getfId(), menus);
			lists.add(rMenu);
		}
		// 添加关联表
		if(lists.size() > 0){
			roleMenuService.insertRoleMenu(lists);
		}
		return new ReturnCode(CodeEnum.SUCCESS);
	}

	/**
	 * 根据id删除角色
	 * 
	 * @param fId
	 * @return
	 */
	@Transactional
	@GetMapping(value = "/delRole/{fId}")
	public ReturnCode delRole(@PathVariable("fId") String fId) {
		// 首先通过id查询到删除的数据
		Role role = roleService.selectByfId(fId);
		if(role == null) {
			return new ReturnCode(CodeEnum.FAIL, "没有找到该数据", null);
		}
		// 根据查询到要删除的菜单的code查询所有下级菜单
		List<Role> roleChildren = roleService.selectRoleByPCode(role.getRoleCode(), null);
		// 对查询到的内容进行判断如果查询到的长度大于0说明该父级角色下有数据，则不能删除，反之可以删除
		if (roleChildren.size() > 0) {
			return new ReturnCode(CodeEnum.FAIL);
		}
		// 通过id删除关联表
		roleMenuService.delRoleMenuByRoleId(fId);
		// 通过ID删除角色
		roleService.delectRoleById(fId);
		// 根据已经删除的角色的PCode查询查询所有的同级角色
		List<Role> roleList = roleService.selectRoleByPCode(role.getRolePCode(), fId);
		roleService.soltRoleList(roleList);
		return new ReturnCode(CodeEnum.SUCCESS);
	}

	/**
	 * 根据ID更新角色
	 * 
	 * @param role
	 * @param bindingResult
	 * @return
	 */
	@PostMapping("/updateRole")
	public ReturnCode updateRole(@RequestBody @Valid UpdateRole updateRole, BindingResult bindingResult) {
		// 判断参数是否合法
		if (bindingResult.hasErrors()) {
			String msg = bindingResult.getFieldError().getDefaultMessage();
			return new ReturnCode(CodeEnum.FAIL, msg, null);
		}
		// 判断更新的角色名是否已经存在
		if (roleService.selectRoleByName(updateRole.getfRoleName()) != null) {
			return new ReturnCode(CodeEnum.FAIL_IS_HAVE);
		}
		// 根据id查询角色
		Role thisRole = roleService.selectByfId(updateRole.getfId());
		// 如果父级code没有变更
		if (thisRole.getRolePCode().equals(updateRole.getRolePCode())) {
			roleService.updateRoleByRole(updateRole);
		} else {
			// 根据要更改的父节点查询下面所有的子节点
			List<Role> pChildren = roleService.selectRoleByPCode(updateRole.getRolePCode(), null);
			// 定义一个新添加的子节点
			String fRoleCode;
			// 如果子节点的长度大于0并且小于9
			fRoleCode = CodeUtil.getCodeByPCode(updateRole.getRolePCode(), pChildren.size());
			// 更改子角色的编号fMenuCode
			updateRole.setRoleCode(fRoleCode);
			// 更新当前子角色的编号
			roleService.updateRoleByRole(updateRole);
			// 获取当前
			List<Role> oldPChildren = roleService.selectRoleByPCode(thisRole.getRolePCode(), null);
			roleService.soltRoleList(oldPChildren);
		}
		// 通过id删除关联表
		roleMenuService.delRoleMenuByRoleId(updateRole.getfId());
		// 添加角色菜单关联
		List<RoleMenu> lists = new ArrayList<RoleMenu>();
		for (String menus : updateRole.getListMenu()) {
			RoleMenu rMenu = new RoleMenu(UUIDUtil.getUUID(), updateRole.getfId(), menus);
			lists.add(rMenu);
		}
		// 添加关联表
		if(lists.size() > 0) {
			roleMenuService.insertRoleMenu(lists);
		}
		return new ReturnCode(CodeEnum.SUCCESS);
	}

	/**
	 * 根据ID查看角色信息
	 * 
	 * @param fId
	 * @return
	 */
	@GetMapping(value = "/selectRoleId/{fId}")
	public ReturnCode selectRoleById(@PathVariable("fId") String fId) {
		if (fId == null) {
			return new ReturnCode(CodeEnum.FAIL);
		}
		Role sysRole = roleService.selectByfId(fId);
		return new ReturnCode(CodeEnum.SUCCESS, sysRole);
	}

	/**
	 * 查看所有的角色
	 * 
	 * @return
	 */
	@GetMapping(value = "/selectAllRole")
	public ReturnCode selectAllRole() {
		// 获取所有的菜单
		List<ReturnRole> liseRoles = roleService.selectAllRole();
		// 将菜单转换为树及结构
		liseRoles = roleService.selectAllRoleTree(liseRoles, "");
		return new ReturnCode(CodeEnum.SUCCESS, liseRoles);
	}

	/**
	 * 根据令牌得到所有的权限
	 * 
	 * @return
	 */
	@PostMapping("/getRole")
	public ReturnCode getRole(HttpServletRequest request) {
		/**
		 * 1根据webToken中的userId查看用户部门 2根据部门id在部门表中查看角色 3根据角色查看用户的菜单
		 */
		// 获取用户id
		String userId = WebTokenUtil.getUserIdByRequest(request);
		List<SysMenu> menuList = roleService.selectRoleByUserId(userId);
		menuService.soltSysMenuList(menuList);
		return new ReturnCode(CodeEnum.SUCCESS, menuList);
	}

	/**
	 * 根据角色id查询权限
	 * 
	 * @param fid
	 * @return
	 */
	@GetMapping("/getMenuByRoleId/{fId}")
	public ReturnCode getMenuByRoleId(@PathVariable("fId") String fid) {
		List<String> roleIds = new ArrayList<String>();
		roleIds.add(fid);
		List<SysMenu> menuList = roleService.selectSysMenuByRoleId(roleIds);
		return new ReturnCode(CodeEnum.SUCCESS, menuList);
	}
}
